package com.library.dao.impl;

import com.library.dao.BookDao;
import com.library.model.Book;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

@Repository
public class BookDaoImpl implements BookDao {

    private final JdbcTemplate jdbcTemplate;

    public BookDaoImpl(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Override
    public List<Book> findAll() {
        String sql = "SELECT * FROM books";
        return jdbcTemplate.query(sql, new BookRowMapper());
    }

    @Override
    public List<Book> findByCriteria(Map<String, Object> criteria) {
        StringBuilder sql = new StringBuilder("SELECT * FROM books WHERE 1=1");
        Object[] params = new Object[criteria.size()];
        int index = 0;

        for (Map.Entry<String, Object> entry : criteria.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();

            if (value != null && !value.toString().isEmpty()) {
                sql.append(" AND ").append(key).append(" LIKE ?");
                params[index++] = "%" + value + "%";
            }
        }

        return jdbcTemplate.query(sql.toString(), new BookRowMapper(), params);
    }

    @Override
    public Book findById(Long id) {
        String sql = "SELECT * FROM books WHERE id = ?";
        try {
            return jdbcTemplate.queryForObject(sql, new BookRowMapper(), id);
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public Book findByIsbn(String isbn) {
        String sql = "SELECT * FROM books WHERE isbn = ?";
        try {
            return jdbcTemplate.queryForObject(sql, new BookRowMapper(), isbn);
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public int save(Book book) {
        String sql = "INSERT INTO books (isbn, title, author, publisher, publication_year, " +
                "category, quantity, available_quantity, created_at, updated_at) " +
                "VALUES (?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW())";

        return jdbcTemplate.update(sql,
                book.getIsbn(),
                book.getTitle(),
                book.getAuthor(),
                book.getPublisher(),
                book.getPublicationYear(),
                book.getCategory(),
                book.getQuantity(),
                book.getAvailableQuantity());
    }

    @Override
    public int update(Book book) {
        String sql = "UPDATE books SET isbn = ?, title = ?, author = ?, publisher = ?, " +
                "publication_year = ?, category = ?, quantity = ?, available_quantity = ?, " +
                "updated_at = NOW() WHERE id = ?";

        return jdbcTemplate.update(sql,
                book.getIsbn(),
                book.getTitle(),
                book.getAuthor(),
                book.getPublisher(),
                book.getPublicationYear(),
                book.getCategory(),
                book.getQuantity(),
                book.getAvailableQuantity(),
                book.getId());
    }

    @Override
    public int delete(Long id) {
        String sql = "DELETE FROM books WHERE id = ?";
        return jdbcTemplate.update(sql, id);
    }

    private static class BookRowMapper implements RowMapper<Book> {
        @Override
        public Book mapRow(ResultSet rs, int rowNum) throws SQLException {
            Book book = new Book();
            book.setId(rs.getLong("id"));
            book.setIsbn(rs.getString("isbn"));
            book.setTitle(rs.getString("title"));
            book.setAuthor(rs.getString("author"));
            book.setPublisher(rs.getString("publisher"));
            book.setPublicationYear(rs.getInt("publication_year"));
            book.setCategory(rs.getString("category"));
            book.setQuantity(rs.getInt("quantity"));
            book.setAvailableQuantity(rs.getInt("available_quantity"));
            book.setCreatedAt(rs.getTimestamp("created_at"));
            book.setUpdatedAt(rs.getTimestamp("updated_at"));
            return book;
        }
    }
}
